<?php
declare (strict_types=1);

namespace app\common\model;

use addons\Pay\facade\Pay;
use addons\Target\facade\Target;
use app\common\controller\Bonus;
use think\facade\Cache;
use think\facade\Event;
use think\helper\Str;

class OrderTemporary extends Order
{
    public static function setTemporary($param, $user): array
    {
        try {
            if (empty($user->parent_id) && $user->id != 1) {
                return ['code' => 205, 'msg' => '请您先完善推荐人信息'];
            }
            if (empty($user->pay_password)) {
                return ['code' => 204, 'msg' => '请您先完善支付密码'];
            }
            if ($param['type'] == 1) {
                $result = ProductSpec::getSettled($param, $user);
            }  else {
                $result = ProductCart::getSettled($param['cart_id'], $user);
            }
            if ($result['code'] != 1) {
                throw new \Exception($result['msg']);
            }
            $productTemporary = $result['data'];
            if (empty($productTemporary)) {
                throw new \Exception('服务器错误，请稍后再试');
            }
            Cache::delete('productTemporaryCartId_' . $user->id);
            //缓存购物车标识
            if (!empty($param['cart_id'])) {
                Cache::set('productTemporaryCartId_' . $user->id, $param['cart_id']);
            }

            //缓存拼团id
            if (!empty($param['pintuan_id'])) {
                Cache::set('productTemporaryPintuanId_' . $user->id.$param['pid'], $param['pintuan_id']);
            }

            Cache::set('productTemporary_' . $user->id, $productTemporary);

            return ['code' => 1, 'msg' => 'success'];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function getTemporary($uid): array
    {
        try {
            $temporary = Cache::get('productTemporary_' . $uid);
            if (empty($temporary)) {
                throw new \Exception('加载失败，请再试一次！');
            }
            $temporary['address'] = Address::getDefault($uid);

            return ['code' => 1, 'msg' => 'success', 'data' => $temporary];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function submit($param, $user): array
    {
        try {
            $address = null;
            $delivery_way = !empty($param['delivery_way']) ? $param['delivery_way'] : 1;
            if($delivery_way == 2){

            }else{
                if (empty($param['address_id'])) {
                    return ['code' => -1, 'msg' => '请选择收货地址'];
                }
                $address = Address::where('id', $param['address_id'])->find();
                if (empty($address)) {
                    return ['code' => -1, 'msg' => '收货地址错误，请重新选择'];
                }
            }

            $temporary = Cache::get('productTemporary_' . $user->id);
            $temporary['remark'] = !empty($param['remark']) ? $param['remark'] : '';
            $temporary['delivery_way'] = $delivery_way;

            return self::createOrder($temporary, $user, $address);
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function createOrder($param, $user, $address): array
    {
        $delivery_way = !empty($param['delivery_way']) ? $param['delivery_way'] : 1;
        $time = time();
        $order_type = $num = $amount = $freight = 0;
        $platoon_id = 0;
        $supplier_id = 0;
        foreach ($param['product'] as &$children) {
            $product = Product::where(['id' => $children['pid'], 'status' => 1])->find();
            if (empty($product)) {
                return ['code' => -1, 'msg' => '商品《' . $product->title . '》已下架'];
            }
            if ($product->spec_open == 2) {
                $specValue = ProductSpec::where(['pid' => $children['pid'], 'merge_title' => $children['spec']])->find();
                if (empty($specValue) || $children['num'] > $specValue->stock) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '-' . $children['spec'] . '》库存不足'];
                }
                $children['icon'] = $specValue->icon ?: $product->icon;
                $children['vip_price'] = $specValue->vip_price;
                //减少库存
                $specValue->stock -= $children['num'];
                $specValue->save();
            } else {
                if ($children['num'] > $product->stock) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '》库存不足'];
                }
                $children['icon'] = $product->icon;
                $children['vip_price'] = $product->vip_price;
            }
            $children['amount'] = round($children['vip_price'] * $children['num'], 2);
            $num += $children['num'];
            //订单总价格
            $amount += $children['amount'];
            $freight += $children['freight'];
            //增加销量
            $product->sales += $children['num'];
            $product->stock -= $children['num'];
            $product->save();
            //定义订单类别
            $order_type = $product->type_id;
            $platoon_id = $product->platoon_id;
            $supplier_id = $product->supplier_id;
        }
        parent::startTrans();
        try {
            $new = parent::create([
                'sn' => 'T' . date('YmdHis') . Str::random(6, 1) . $user->id,
                'uid' => $user->id,
                'order_type' => $order_type,
                'num' => $num,
                'total_amount' => $amount,
                'freight' => $freight,
                'real_amount' => round($amount + $freight, 2),
                'address_id' => !empty($address) ? $address->id : 0,
                'receiver' => !empty($address) ? $address->nickname : '',
                'receiver_tel' => !empty($address) ? $address->tel : '',
                'province' => !empty($address) ? $address->province : '',
                'city' => !empty($address) ? $address->city : '',
                'district' => !empty($address) ? $address->district : '',
                'address_details' => !empty($address) ? $address->details : '',
                'remark' => $param['remark'],
                'status' => 1,
                'expire_time' => round(Cache::get('system')['payment_timeout'] * 60 + $time),
                'platoon_id' => $platoon_id,
                'supplier_id' => $supplier_id,
                'delivery_way' => $delivery_way,
            ]);
            $walk = ['order_id' => $new->id, 'uid' => $user->id, 'create_time' => $time, 'update_time' => $time];
            array_walk($param['product'], function (&$value, $key, $walk) {
                $value = array_merge($value, $walk);
            }, $walk);
            (new OrderProduct())->insertAll($param['product']);
            $cart_id = Cache::get('productTemporaryCartId_' . $user->id);
            if ($cart_id) {
                ProductCart::destroy(['id' => $cart_id], true);
                Cache::delete('productTemporaryCartId_' . $user->id);
            }

            $pintuan_id = Cache::get('productTemporaryPintuanId_' . $user->id.$param['product'][0]['pid']);
            if($pintuan_id){
                $pintuaninfo = Pintuan::where(['id'=>$pintuan_id,'status'=>2])->find();
                if(!empty($pintuaninfo) && empty($pintuaninfo['order_id']) ){
                    Pintuan::update(['order_id'=>$new->id],['id'=>$pintuan_id]);
                }
                Cache::delete('productTemporaryPintuanId_' . $user->id.$param['product'][0]['pid']);
            }

            Cache::delete('productTemporary_' . $user->id);

            //获取拼团信息

            parent::commit();

            return ['code' => 1, 'msg' => 'success', 'data' => $new->id];
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function getPayment($id, $user): array
    {
        try {
            $info = parent::field('id,sn,order_type,real_amount,expire_time,status')
                ->where(['id' => $id, 'uid' => $user->id])->find();
            if (empty($info)) {
                throw new \Exception('无效订单');
            }
            if ($info->getData('status') != 1) {
                throw new \Exception('订单已支付或已失效');
            }
            $info->surplus_time = round(($info->expire_time - time()) * 1000);
            $data['order'] = $info;
            $data['method'] = self::payWay($info->order_type);

            return ['code' => 1, 'msg' => 'success', 'data' => $data];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function payWay($order_type = ''): array
    {
        return match ($order_type) {
            1 => self::getPaymentMethod(['currency', 'green']),
            2 => self::getPaymentMethod(['coupon']),
            //default => self::getPaymentMethod(['currency'])
        };
    }

    public static function getPaymentMethod($data): array
    {
        $method = [];
        foreach ($data as $item) {
            if (in_array($item, ['wechat', 'alipay'])) {
                $is_pay = 0;
                $icon = $item;
            } else {
                $is_pay = 1;
                $icon = 'wallet';
            }
            $method[] = [
                'title' => get_pay_way($item),
                'pay_way' => $item,
                'icon' => '/static/admin/img/' . $icon . '.png',
                'is_pay_password' => $is_pay
            ];
        }

        return $method;
    }

    public static function payment($param, $user): array
    {
        try {
            $info = parent::where(['id' => $param['id']])->find();
            if ($info->getData('status') != 1) {
                throw new \Exception('订单已支付或已失效');
            }
            $pay_way = $param['pay_way'];
            switch ($pay_way) {
                case "currency":
                case "green":
                case "coupon":
                    if (md5($param['pay_password']) != $user->pay_password) {
                        throw new \Exception('支付密码错误');
                    }
                    if ($info->real_amount > $user->assets->$pay_way) {
                        throw new \Exception(get_pay_way($pay_way) . '账户余额不足');
                    }

                    return self::operations($info, $user, $pay_way);
                default:
                    throw new \Exception('暂未开放');
            }

        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function operations($info, $user, $pay_way, $transaction_id = ''): array
    {
        parent::startTrans();
        try {
            $system = Cache::get('system');
            $info->status = $info->delivery_way == 2 ? 7 : 2;
            if (!empty($transaction_id)) {
                $info->transaction_id = $transaction_id;
            }
            $info->pay_state = 1;
            $info->pay_way = $pay_way;
            $info->pay_time = time();
            $info->save();
            if (!in_array($pay_way, ['wechat', 'alipay'])) {
                Target::Account()->basics($user->id, $pay_way, $info->real_amount, '购买商品', '-')->createNormal();
            }

            $orderAmount = $info->real_amount;
            if($info->freight > 0){
                $orderAmount -= $info->freight;
            }
            switch ($info->order_type){
                case 1:
                    if ($user->is_active == 1) {
                        $user->is_active = 2;
                        $user->active_type = 1;
                        $count = User::where(['parent_id' => $user->parent_id, 'is_active' => 2])->count();
                        $user->active_sort = $count + 1;
                        $user->active_time = time();
                        if ($user->parent_id) {
                            User::where(['id' => $user->parent_id])->inc('push_num')->save();
                            $renewData[] = ['fx' => '+', 'field' => 'team_num', 'num' => 1];
                        }
                        Event::trigger('Statistics', ['key' => 'formal_user', 'value' => 1]);
                    }
                    $user->my_total += $orderAmount;
                    $user->save();
                    $renewData[] = ['fx' => '+', 'field' => 'team_total', 'num' => $orderAmount];
                    Relation::renewTeamTotal($user->id, $renewData);
                    $renewNodeData[] = ['fx' => '+', 'field' => 'total', 'num' => $orderAmount];
                    $renewNodeData[] = ['fx' => '+', 'field' => 'surplus', 'num' => $orderAmount];
                    UserNode::renewTeamTotal($user->id, $renewNodeData);

                    /** @公排 */
                    if($user->platoon_id == 0){
                        $user->platoon1_amount += $orderAmount;
                        if($user->platoon1_amount >= 1000){
                            $platoonId = 1;
                            $user->platoon_id = 1;
                            $pUser = User::where('id', $user->parent_id)->find();
                            if($pUser){
                                if($pUser->platoon_id == 1){
                                    $pUser->push_platoon1 ++;
                                    $pUser->save();

                                    if($pUser->push_platoon1 > 1){
                                        if($pUser->assets->contribute < 5){
                                            Target::Account()->basics($pUser->id, 'contribute', $system['platoon_zt_contribute'.$pUser->platoon_id], "邀请VIP得贡献值", '+')->createNormal();
                                        }
                                        if($pUser->push_platoon1 == 2){
                                            Account::bonusEntry($pUser->id, 1500, 'VIP分红', $user->id, 1, $info->id);
                                            $msg = "会员【ID：{$pUser->id}】推荐【ID：{$user->id}】，人数达到2，获得VIP分红";
                                            Logs::adds($msg);
                                        }elseif($pUser->push_platoon1 == 3){
                                            $sub = self::getSubUser($pUser, $pUser->platoon_id);
                                            Platoon::_add($sub, $info, $pUser->platoon_id);
                                        }elseif ($pUser->push_platoon1 > 3 && $pUser->push_platoon1 <= 6 && !$pUser->out_1){
                                            $sub = self::getSubUser($pUser, $pUser->platoon_id);
                                            Platoon::_add($sub, $info, $pUser->platoon_id);
                                        }
                                    }
                                }elseif($pUser->platoon_id == 2){
                                    if(!$pUser->is_queue){
                                        $pUser->platoon2_push_vip ++ ;
                                        if($pUser->platoon2_push_vip >= Cache::get('system')['platoon2_zt_vip'] && $pUser->platoon2_bonus < Cache::get('system')['platoon_max_amount2']  && !$pUser->out_2){
                                            if($pUser->assets->contribute < 15) {
                                                Target::Account()->basics($pUser->id, 'contribute', $system['platoon_zt_contribute2'], "经理邀请VIP得贡献值", '+')->createNormal();
                                            }
                                            $sub = self::getSubUser($pUser, $pUser->platoon_id);
                                            Platoon::_add($sub, $info, $pUser->platoon_id);
                                            $pUser->is_queue = 0;
                                            $pUser->platoon2_push_vip = 0;
                                        }
                                        $pUser->save();
                                    }
                                }elseif($pUser->platoon_id == 3){
                                    if(!$pUser->is_queue){
                                        $pUser->platoon3_push_vip ++ ;
                                        if($pUser->platoon3_push_vip >= Cache::get('system')['platoon3_zt_vip'] && $pUser->platoon3_bonus < Cache::get('system')['platoon_max_amount3'] && !$pUser->out_3){
                                            if($pUser->assets->contribute < 25) {
                                                Target::Account()->basics($pUser->id, 'contribute', $system['platoon_zt_contribute3'], "店长邀请VIP得贡献值", '+')->createNormal();
                                            }
                                            $sub = self::getSubUser($pUser, $pUser->platoon_id);
                                            Platoon::_add($sub, $info, $pUser->platoon_id);
                                            $pUser->is_queue = 0;
                                            $pUser->platoon3_push_vip = 0;
                                        }
                                        $pUser->save();
                                    }
                                }

                            }
                        }
                        $user->save();
                    }

                    if($user->platoon_id == 1 && $user->out_1 == 1){
                        $user->platoon2_amount += $orderAmount;
                        if($user->platoon2_amount >= 5000){
                            $platoonId = 2;
                            $user->platoon_id = 2;
                            $user->level_id = 2;//区县代理

                            if($user->assets->contribute < 15) {
                                Target::Account()->basics($user->id, 'contribute', $system['platoon_zt_contribute' . $platoonId], "经理消费得贡献值", '+')->createNormal();
                            }
                            $sub = self::getSubUser($user, $platoonId);
                            Platoon::_add($sub, $info, $platoonId);
                        }
                        $user->save();
                    }

                    if($user->platoon_id == 2 && $user->out_2 == 1){
                        $user->platoon3_amount += $orderAmount;
                        if($user->platoon3_amount >= 25000){
                            $platoonId = 3;
                            $user->platoon_id = 3;
                            $user->level_id = 3;//市级代理
                            if($user->assets->contribute < 25) {
                                Target::Account()->basics($user->id, 'contribute', $system['platoon_zt_contribute' . $platoonId], "店长消费得贡献值", '+')->createNormal();
                            }
                            $sub = self::getSubUser($user, $platoonId);
                            Platoon::_add($sub, $info, $platoonId);
                        }
                        $user->save();
                    }

                    /** @公排 */
                    break;
            }

            Event::trigger('Statistics', ['key' => 'income', 'value' => $info->real_amount]);
            parent::commit();

            return ['code' => 1, 'msg' => '支付成功'];
        } catch (\Exception $e) {
            parent::rollback();
            Logs::exception($e);
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function pushUpdate($pUser,$user,$platoonId, $info, $system)
    {
        try{
            $field = 'push_platoon'.$platoonId;
            $title = '';
            if($platoonId == 1){
                $title = 'VIP';
            }elseif($platoonId == 2){
                $title = '经理';
            }elseif($platoonId == 3){
                $title = '店长';
            }
            if($pUser->$field == 2){
                $amount = $system['platoon_amount'.$platoonId];
                Account::bonusEntry($pUser->id, $amount, "{$title}分红", $user->id, $platoonId, $info->id);
                Target::Account()->basics($pUser->id, 'contribute', $system['platoon_zt_contribute'.$platoonId], "邀请{$title}得贡献值", '+')->createNormal();
            }elseif ($pUser->$field == 3){
                $newUser = self::getSubUser($pUser, $platoonId);
                Platoon::_add($newUser, $info);
            }elseif ($pUser->$field > 3){
                Target::Account()->basics($pUser->id, 'contribute', $system['platoon_zt_contribute'.$platoonId], "邀请{$title}得贡献值", '+')->createNormal();
                $platoon = Platoon::where(['master_uid'=>$pUser->id, 'level'=>$platoonId])->find();
                if($platoon){
                    Platoon::platoon($platoonId, $platoon, $pUser, $info);
                }
            }
        }catch (\Exception $e){
            Logs::exception($e);
        }

    }

    public static function getSubUser($user, $platoonId)
    {
        $newSubData = $user->toArray();
        unset($newSubData['id']);
        $newSubData['code'] = generateUserCode();
        $newSubData['platoon_id'] = $platoonId;
        $newSubData['is_sub'] = 1;
        $newSubData['node_id'] = UserNode::getNodeId($platoonId);
        $newSubData['node_type'] = 2;
        $newSubData['position'] = 1;
        $newSubData['is_active'] = 2;
        $newSubData['active_time'] = time();
        $newSubData['master_id'] = $user->id;
        $newSubData['nickname'] = $user->nickname.'（C）';
        $newSubData['create_time'] = time();
        $newSubData['update_time'] = time();

        $newUser = User::create($newSubData);
        return $newUser;
    }

    public static function getNodeId($parentId)
    {
        //$parent = User::find($parentId);
        $childNode = User::where(['node_id'=> $parentId, 'position'=>1])->find();
        if(!$childNode){
            return $parentId;
        }else{
            return self::getNodeId($childNode->id);
        }
    }

    public static function edit($param, $user): array
    {
        parent::startTrans();
        try {
            $info = parent::where(['id' => $param['id'], 'uid' => $user->id])->find();
            if (empty($info)) {
                throw new \Exception('此订单不存在');
            }
            switch ($param['type']) {
                case 'cancel': //取消订单
                    if ($info->getData('status') != 1 || $info->pay_state) {
                        throw new \Exception('此订单已支付，无法取消');
                    }
                    self::cancel($info);
                    $msg = '订单取消成功';
                    break;
                case "remind": //提醒发货
                    if ($info->getData('status') != 2) {
                        throw new \Exception('此订单未支付或已发货');
                    }
                    if ($info->is_remind) {
                        throw new \Exception('您已提醒发货了');
                    }
                    $info->is_remind = 1;
                    $info->remind_time = time();
                    $info->save();
                    $msg = '提醒发货成功';
                    break;
                case "receipt": //确认收货
                    if ($info->getData('status') != 3) {
                        throw new \Exception('此订单无需收货');
                    }
                    self::receipt($info);
                    $msg = '确认收货成功';
                    break;
                default:
                    throw new \Exception('操作有误');
            }
            parent::commit();

            return ['code' => 1, 'msg' => $msg];
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function cancel($info): bool|string
    {
        try {
            $info->status = 6;
            $info->cancel_time = time();
            $info->save();
            Event::trigger('Operation', $info->id);

            return true;
        } catch (\Exception $e) {

            return $e->getMessage();
        }
    }

    public static function receipt($info, $is_auto = false): bool|string
    {
        try {
            $time = time();
            $info->status = 5;
            $info->receipt_time = $time;
            $info->finish_time = $time;
            if ($is_auto) $info->auto_receipt_time = $time;
            $info->save();
            $content = "您的订单【{$info->sn}】确认收货成功";
            UserNotify::add(2, $info->uid, '订单收货', $content, $info->id);

            return true;
        } catch (\Exception $e) {

            return $e->getMessage();
        }
    }

    /**
     * 订单支付超时自动取消
     * 定时
     */
    public static function autoCancel(): array
    {
        parent::startTrans();
        try {
            parent::where(['status' => 1, 'pay_state' => 0])->where('expire_time', '<=', time())->select()->each(function ($item) {
                self::cancel($item);
            });
            parent::commit();

            return ['code' => 1, 'msg' => '执行成功'];
        } catch (\Exception $e) {
            parent::rollback();
            Logs::write('logs/order-autoCancel.log', $e->getMessage());

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 订单自动确认收货
     * 定时
     */
    public static function autoReceipt(): bool|string
    {
        try {
            parent::where(['status' => 3])->where('auto_receipt_time', '<=', time())->select()->each(function ($item) {
                self::receipt($item, true);
            });

            return true;
        } catch (\Exception $e) {

            return $e->getMessage();
        }
    }
}